/**
 * @file:          ch32v30x_module.h
 * @brief:
 * @details:
 * @author:        wjh
 * @date created:  2023.06.09
 * @version:       1.0.0
 * @par copyright (c):
 *
 * @par history (desc):
 *   version:1.0.0, wjh, 2023.06.09,18:31:37
 */
#ifndef _CH32V30X_MODULE_H_
#define _CH32V30X_MODULE_H_

/* Include Files **************************************************************/
#include "Datatype.h"

// #define HIL 1
#ifndef HARDWARE_DISABLE

#include "debug.h"

#endif

/* Macro Definition ***********************************************************/
#define UART_RX_FIFO_SIZE 100
extern int8 UartRxBuff[];

#ifndef HARDWARE_DISABLE
#define ENABLE_GLOBAL_INTERRUPT() __enable_irq()
#define DISABLE_GLOBAL_INTERRUPT() __disable_irq()
// #define SPI_CS_H() GPIO_SetBits(GPIOA, GPIO_Pin_4);
// #define SPI_CS_L() GPIO_ResetBits(GPIOA, GPIO_Pin_4);
#define SPI_CS_H() (GPIOA->BSHR = GPIO_Pin_4)
#define SPI_CS_L() (GPIOA->BCR = GPIO_Pin_4)
#else
#define ENABLE_GLOBAL_INTERRUPT()
#define DISABLE_GLOBAL_INTERRUPT()
#endif

#define FLASH_PAGE_SIZE (4096)

#define ADC_NUM1 0
#define ADC_NUM2 1
#define ADC_CHANNEL_REGULAR 0
#define ADC_CHANNEL_INJECT_1 1
#define ADC_CHANNEL_INJECT_2 2
#define ADC_CHANNEL_INJECT_3 3
#define ADC_CHANNEL_INJECT_4 4
#define ADC_TEMP_AVG_SLOPE (4.3) /* mv/C */
#define ADC_TEMP_V25 (1.40F)     /* V */

#ifndef HARDWARE_DISABLE
#define MCU_REFER_VOLT_MV() (int32_t)((*(uint32_t *)0x1FFFF720) & 0x0000FFFF)          /* mV */
#define MCU_REFER_TEMPER_C() (int32_t)(((*(uint32_t *)0x1FFFF720) >> 16) & 0x0000FFFF) /* C */
#else
#define MCU_REFER_VOLT_MV() (int32_t)(1400) /* mV */
#define MCU_REFER_TEMPER_C() (int32_t)(25)  /* C */
#endif

/* Data Type Define ***********************************************************/
enum InputPulseTriggerMode_E
{
    InputPulseTrigger_BothEdge = 0,
    InputPulseTrigger_RisingEdge = 1,
    InputPulseTrigger_FallingEdge = 2,
    InputPulseTrigger_Custom = 3,
};

typedef struct ch32v30x_module
{
    /* public data */
    void *_;
    uint32 param_sysclk_hz;
    uint32 param_HSE_hz;
    float32 param_task_period_s;
    float32 param_pwm_period_s;
    uint32 param_uart_baudrate;
    uint16 param_input_pulse_counter_period_count;
    uint16 param_input_pulse_counter_filter_level;
    uint16 param_input_pulse_counter_trigger_mode;

    uint32 sysclk_hz;
    uint32 pll_mull;
    uint32 pll_mull_reg;
    uint32 pll_source;
    uint32 rcc_sws;
    uint8 rcc_hpre;
    uint8 us_count;
    uint16 ms_count;
    uint16 pwm_period_count;
    uint16 adc1_offset;
    uint16 adc2_offset;
    uint16 pwm_ch1_cmp_value;
    uint16 pwm_ch2_cmp_value;
    uint16 pwm_ch3_cmp_value;
    uint16 pwm_ch4_cmp_value;

    /* private data */

    /* public method */
    void (*ConfigParam)(struct ch32v30x_module *self);
    uint8 (*Init)(struct ch32v30x_module *self);
    void (*InitSystem)(struct ch32v30x_module *self);
    void (*InitClock)(struct ch32v30x_module *self);
    void (*InitGpio)(struct ch32v30x_module *self);
    void (*InitAdc)(struct ch32v30x_module *self);
    void (*InitUart)(struct ch32v30x_module *self);
    void (*InitDMA)(struct ch32v30x_module *self);
    void (*InitPwm)(struct ch32v30x_module *self);
    void (*InitTimmer)(struct ch32v30x_module *self);
    void (*InitSpi)(struct ch32v30x_module *self);
    void (*InitInternalFlash)(struct ch32v30x_module *self);
    void (*InitInputPulseCounter)(struct ch32v30x_module *self);
    void (*InitExternalInterrupt)(struct ch32v30x_module *self);
    void (*InitIWDG)(struct ch32v30x_module *self);
    void (*InitWWDG)(struct ch32v30x_module *self);
    void (*InitDelay)(struct ch32v30x_module *self);
    void (*GpioToggle)(uint16 gpio);
    void (*GpioSet)(uint16 gpio);
    void (*GpioReset)(uint16 gpio);
    uint16 (*GpioRead)(uint16 gpio);
    void (*DelayMs)(struct ch32v30x_module *self, uint16 x_ms);
    void (*DelayUs)(struct ch32v30x_module *self, uint16 x_us);
    int16 (*AdcGetResult)(uint16_t adc_num, uint16 channel);
    void (*StartTimmer)();
    void (*StopTimmer)();
    void (*GpioPinInit)(struct ch32v30x_module *self, uint16 gpio, uint16 gpio_mode);
    uint16 (*GpioModeTranslate)(uint16 gpio_mode);
    void (*SetPwm)(struct ch32v30x_module *self, uint16 pwm_channel, float32 pwm_duty);
    void (*SetAllPwm)(struct ch32v30x_module *self, float32 pwm_duty_ch1, float32 pwm_duty_ch2, float32 pwm_duty_ch3, float32 pwm_duty_ch4);
    uint8 (*SPI_WriteReadData)(uint16 *write_data, uint8 *read_data, uint16 data_len, uint16 over_time);
    uint8 (*SPI_WriteReg)(uint8 addr, uint8 *data, uint16 data_len);
    uint8 (*SPI_ReadReg)(uint8 addr, uint8 *data, uint16 data_len);
    uint8 (*SPI_WriteByte)(uint8 data);
    uint8 (*SPI_ReadByte)();
    void (*EnableInterrupt)();
    void (*EnableNvicInterrupt)();
    void (*DisableNvicInterrupt)();
    void (*ADC_StartConversion)();
    void (*ADC_WaitConversionComplete)();
    void (*FlashWriteOnePage256Bytes)(uint32 flash_start_addr, uint32 addr_n_256, uint32 *data_buff);
    void (*FlashWriteHalfWord)(uint32 flash_start_addr, uint32 data_addr_offset, uint16 data);
    void (*FlashEraseOnePage256Bytes_Fast)(uint32 flash_start_addr, uint32 addr_n_256);
    void (*FlashEraseOnePage32KBytes_Fast)(uint32 flash_start_addr, uint32 addr_n_32k);
    void (*FlashEraseOnePage32KBytes)(uint32 flash_start_addr, uint32 flash_end_addr);
    void (*FlashUnlockFast)();
    void (*FlashLockFast)();
    void (*FlashUnlock)();
    void (*FlashLock)();
    void (*FlashClearFlag)();
    uint16_t (*GetInputPulseCounter)();
    void (*ClearInputPulseCounter)();
    void (*SetInputPulseCounter)(uint16_t count);
    void (*AddInputPulseCounter)(uint16_t count);
    void (*EnableInputPulseCounter)();
    void (*DisableInputPulseCounter)();
    void (*StartUartDMA)();
    uint8 (*UartReceiveOnePackFinished)(struct ch32v30x_module *self, uint16 *data_len);
    void (*ResetSystem)();
    void (*InitPinNum)(struct ch32v30x_module *self);
    void (*UartDMASend)(uint8_t *data, uint8_t len);
    void (*SetInputPulseCouterCountUp)();
    void (*SetInputPulseCouterCountDown)();
    void (*EnableIWDG)();
    void (*EnableWWDG)();
    void (*FeedIWDG)();
    void (*FeedWWDG)();
    void (*UartSendOneByte)(uint16_t data);
    void (*DMA_Send)();
    void (*DMAAdv_Send)();
    void (*DMAHex_Send)();
    void (*JumpToBootLoader)();
    void (*HCLKSetToDiv1)();
    void (*HCLKSetToDiv2)();
    uint8_t (*ITStatusCheck_TimeUpdate)();
    uint8_t (*ITStatusCheck_EXTI)();
    void (*ITStatusClear_TimeUpdate)();
    void (*ITStatusClear_EXTI)();
    uint8_t (*GetTimDir)();

    /* private method */

} ch32v30x_module;

/* Variable Declare ***********************************************************/

/* Inline Function Define *****************************************************/

/* Function Declare ***********************************************************/
#endif
